#include "stdafx.h"

#include "DBServiceStackWalker.h"

BOOL DBServiceStackWalker::ShowCallstack(
    HANDLE hThread, 
    const CONTEXT *context, 
    PReadProcessMemoryRoutine readMemoryFunction,
    LPVOID pUserData // optional to identify some data in the 'readMemoryFunction'-callback
    )
{
	m_szStackMessage = new char[MAX_STACK_MESSAGE];

	BOOL bResult = __super::ShowCallstack(hThread, context, readMemoryFunction, pUserData);

	wchar_t* szOutputMessage = new wchar_t[MAX_STACK_MESSAGE];
	::MultiByteToWideChar(CP_ACP, 0, m_szStackMessage, -1, szOutputMessage, MAX_STACK_MESSAGE);
	WriteEventLogEntry(szOutputMessage, EVENTLOG_ERROR_TYPE);

	delete szOutputMessage;
	delete m_szStackMessage; 
	
	return bResult;
}

void DBServiceStackWalker::OnOutput(LPCSTR szText)
{
	strcat_s(m_szStackMessage, MAX_STACK_MESSAGE, (const char*)szText);
	__super::OnOutput(szText);
}


void DBServiceStackWalker::WriteEventLogEntry(PWSTR pszMessage, WORD wType)
{
    HANDLE hEventSource = NULL;
    LPCWSTR lpszStrings[2] = { NULL, NULL };

    hEventSource = RegisterEventSource(NULL, L"DBComputingService");
    if (hEventSource)
    {
        lpszStrings[0] = L"DBComputingService";
        lpszStrings[1] = pszMessage;

        ReportEvent(hEventSource,  // Event log handle
            wType,                 // Event type
            0,                     // Event category
            0,                     // Event identifier
            NULL,                  // No security identifier
            2,                     // Size of lpszStrings array
            0,                     // No binary data
            lpszStrings,           // Array of strings
            NULL                   // No binary data
            );

        DeregisterEventSource(hEventSource);
    }
}

LONG WINAPI ExpFilter(EXCEPTION_POINTERS* pExp, DWORD dwExpCode)
{
  DBServiceStackWalker sw;
  sw.ShowCallstack(GetCurrentThread(), pExp->ContextRecord);
  return EXCEPTION_EXECUTE_HANDLER;
}
